[sample #12451] [v2] Per Pod/LB IP proxy ARP#241
Conversation
The orchestrator adds a 6th serial agent call after the 5 personas. On a large/ slow PR the cumulative time (personas ~8m parallel + orchestrator poll up to 10m + posting) exceeded the 15m job cap, cancelling the whole job before the orchestrator's own graceful degradation could post-all — e.g. sample PR #241 posted zero comments. Raise to 30m so the job outlives the worst-case serial path and graceful degradation can run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* eval-benchmark-pr.py: compare two iterations of a duplicate PR Reworks the eval tool from human-vs-Council (single PR) into a two-iteration comparison: `eval-benchmark-pr.py <prA> <prB>` reports how the Council's inline comments changed across two duplicate PRs of the same original — shared, only-in-A, only-in-B — overall and per persona (same-persona only). Matching is location-based (option A): same (persona, file, line). Both PRs reproduce the same diff so lines align; deterministic, no evaluator variance. Semantic (LLM) matching deferred to the scoring phase. The doc also records the two-iteration design, the LLM-variance caveat, and the future human-in-the-loop good/bad labeling direction (path to a single score). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Raise Council job timeout 15→30m for the orchestrator's serial call The orchestrator adds a 6th serial agent call after the 5 personas. On a large/ slow PR the cumulative time (personas ~8m parallel + orchestrator poll up to 10m + posting) exceeded the 15m job cap, cancelling the whole job before the orchestrator's own graceful degradation could post-all — e.g. sample PR #241 posted zero comments. Raise to 30m so the job outlives the worst-case serial path and graceful degradation can run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address Council review on eval tool (#242) 1. detail() no longer over-reports multiplicity — uses Counter subtraction (ka - kb) to emit exactly the unmatched count per (persona,file,line) key. 2. Only count comments authored by the Council bot (user.type == "Bot") — a human reply quoting a marker is no longer tallied as Council output. 3. Robust persona parse via regex council-of-claudes:inline:([\w-]+). 4. Strip the "<badge> **Persona** —" prefix from stored bodies so detail bullets don't double the persona (label() already renders it). 5. Fix inaccurate doc strings (PERSONAS emoji comment; clean() overclaim). Also carry comment id for stable per-key ordering. Deferred (YAGNI for an internal script that will evolve for the scoring phase): argparse/--fork/--limit/--json, helper extraction, full markdown sanitization, line-0 unanchored bucketing. Pagination was a non-issue (gh_lines uses --paginate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c796b13 to
e4939cb
Compare
b991e60 to
7e29107
Compare
There was a problem hiding this comment.
🔎 Council of Claudes — Correctness
Note
Correctness lens · bugs · completeness · concurrency · edge cases
3 potential correctness issues
-
Manager lifecycle: the new proxy neighbor managers spin long-lived listener goroutines, but there’s no clear shutdown path when Felix stops. InternalDataplane doesn’t appear to cancel these contexts on shutdown, which can leave sockets/goroutines open until process exit. Consider wiring a cleanup in the dataplane’s Stop/teardown to call m.cancel() for each manager (you already store them in dp.proxyNeighManagers) so listeners are deterministically stopped.
-
Feature enable check is case-sensitive in one place. Config parsing allows case-insensitive values; comparing with a case-sensitive string can leave the feature disabled when users set a different case form.
-
FV test: invalid use of new() with a constant value for HostSubnetNeighResponses. This won’t compile.
Line-specific findings:
🤖 Council of Claudes · 4 inline comment(s)
There was a problem hiding this comment.
🧪 Council of Claudes — Maintainability & Tests
Tip
Maintainability & Tests lens · simplicity · tests · docs · idioms
Well-tested overall with strong UT/FV/E2E coverage; a few maintainability nits and one small missing unit test around config gating
- Good job on shipping comprehensive tests at three layers:
- Unit tests thoroughly exercise ARP/NDP listeners, reconciliation, GARP/UNA, pool filtering, LB VIP selection, and live-migration.
- FV drives the calc graph end-to-end including the new Service status → ServiceUpdate path.
- E2E adds dual-stack coverage with realistic L2 topology and skips appropriately via RequiresKindNetwork.
- The new manager is a large single file (~700 lines) but logically cohesive. Consider modest refactors over time (e.g., isolating ARP vs NDP listener code) if it grows further.
- Two maintainability improvements would reduce future friction:
- Avoid stringly-typed config checks (use consistent parsing/enum and case-insensitive comparisons) and centralize gating in one place.
- Deduplicate docker-network/subnet helper functions shared between e2e and FV into a common utility to reduce drift.
- One targeted test ask: add a small unit test around the HostSubnetNeighResponses gating in NewIntDataplaneDriver so a future change doesn’t accidentally register the manager when Disabled.
Line-specific findings:
🤖 Council of Claudes · 6 inline comment(s)
There was a problem hiding this comment.
🛡️ Council of Claudes — Security
Caution
Security lens · validation · secrets · authz · isolation
3 potential security issues
- Architectural observation: This feature exposes pod and LoadBalancer IPs at L2 to any hosts on the same subnet when enabled. Even if Calico policy still applies at L3/L4, clusters that assume pods are not directly reachable from the host LAN may find this weakens isolation. Carefully consider the default and provide clear operator guidance. Also verify that the interface monitor feeding ifaceAddrsUpdate honors Felix’s InterfaceExclude setting so sensitive uplinks can be excluded from proxy ARP/NDP.
🤖 Council of Claudes · 4 inline comment(s)
There was a problem hiding this comment.
Council of Claudes — Nell
Important
Nell lens · simulated reviewer · simplicity · naming · error handling · keep useful comments
2 potential correctness issues
- Behavioural default: Enabling HostSubnetNeighResponses by default feels risky; I think we usually default new dataplane-affecting features to Disabled and then flip later once hardened. Worth confirming intent?
- Error handling: newProxyNeighManager panics on netlink init failure. IIUC this would take down Felix rather than propagate a clean error to the dataplane loop/startup; can we return err up instead?
Also, a few simplifications/clean‑ups:
- We now have near-duplicate helpers (docker network inspect + subnet offset math) in both e2e and felix/fv; can we deduplicate into a small shared test util?
- Case/normalisation: we compare config and service types by exact string. Given the config parser is case-insensitive, maybe normalise once (or use strings.EqualFold) to avoid surprises.
- InternalDataplane stores proxyNeighManagers but doesn't use the slice later; do we need to keep that field?
Finally, is the plumb‑through from FelixConfiguration->felix/config.Config->dataplane complete for this field? I see the CRD field, docs, and the Config field/tag, and it’s passed into int_dataplane.Config, but I don’t see any conversion code changes — suspect it’s automatic, but worth a quick double‑check that a non-default YAML actually reaches configParams.HostSubnetNeighResponses.
🤖 Council of Claudes · 3 inline comment(s)
There was a problem hiding this comment.
Council of Claudes — Casey
Warning
Casey lens · simulated reviewer · testing discipline · API design · simplicity · robustness
1 robustness issue (panic in felix), plus a few naming/clarity items and small maintainability nits. One policy question: do we really want this enabled by default?
- Naming/clarity: “Neigh” reads a bit cryptic to me across the API, config, file/type names, and docs. Could we spell out “Neighbor” (and be consistent with American English “neighbor” vs “neighbour”) and/or lean on a term like “ProxyNeighbor” to capture ARP+NDP more directly? WDYT?
- API/defaults: Perhaps I’ve forgotten the context — is there a reason this ships enabled-by-default? Responding to ARP/NDP from the host is a behavior change that might surprise environments relying on L3 reachability/BGP-only paths. I could be swayed either way, but I’d expect “Disabled” as the safer initial default.
- Manager enable check: We’re string-matching “PodsAndLoadBalancers” in a few places — can we avoid magic strings (use constants or normalize to a bool)?
- Regex safety: Building a regexp from WorkloadIfacePrefixes without quoting can misinterpret metacharacters in prefixes; we should QuoteMeta.
- Tests: e2e/FV look generally good and labeled rather than self-skipping — thanks. One question on FV: adding a new external image (netshoot) tends to add flake surface. Is there a way to reuse our existing infra image or a lighter image we already pull?
🤖 Council of Claudes · 8 inline comment(s)
* Orchestrator: resubmit a fresh task once if it hangs #240 (calico#12960) hung the orchestrator twice at the poll cap even though its input was the *smallest* of the three benchmark PRs (25 comments vs #241's 42, which completed in ~2.5m) — so it's a server-side stuck task, not payload size. A healthy orchestrator dedups in ~2-3 min, so a long poll means stuck-not-slow. reviewWithAgent now takes a maxPollMs; orchestrateDedup makes up to ORCH_ATTEMPTS (2) attempts, each a *fresh* task (distinct msgId) bounded by ORCH_POLL_MS (7m), so a stuck task gets a second shot — a fresh submission usually doesn't recur. Two 7m attempts still fit inside the 30m job timeout alongside personas + posting. Still lossless: if all attempts produce nothing, post everything unfiltered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Richer error diagnostics for agent calls The recurring #240 hang only logged "poll error (fetch failed)" and "did not complete within 600s" — not enough to tell a stuck server-side task from a network problem. Add: - errDetail(): surfaces e.cause (ECONNRESET / UND_ERR_* / etc.) that Node's fetch hides behind generic "fetch failed" / "terminated" messages. - rpc(): on non-2xx, include statusText + a short response-body snippet (5xx gateways often explain themselves there). - poll timeout: report last task state + counts of successful polls vs poll errors — so "last state: working, 84 polls ok, 0 poll errors" clearly means stuck-server-side, vs poll errors meaning network. - warn explicitly when a task can't be submitted after 3 attempts. Logging-only (plus reading the error body); behavior unchanged. Validated with mock tests (happy path, cause surfaced, submit-failure warning, graceful post-all). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address Council review on #244 1. Include GITHUB_RUN_ATTEMPT in agent msgIds (orchestrator + personas). The run id alone is stable across GitHub "Re-run jobs", so a re-run could reuse a prior msgId and get a stale server-side task. RUN_ATTEMPT (+ per-attempt suffix) guarantees a fresh task on every submission. 2. Retry the orchestrator on an UNPARSEABLE response too, not just on no-response: parse moved into the attempt loop, so a garbled/fenced reply gets a fresh-task retry within the same budget. Still lossless — fall through to post-all. 3. Downgrade the "resubmitting a fresh task" log from warning to info (the preceding timeout is already a warning; the resubmit is expected behaviour). Deferred (consistent w/ prior calls): HTTPS/host allowlist on agent URL (applies to all agents → hardening backlog), env-overridable knobs, JSDoc, reviewFn test-seam/Jest harness, maxPollMs clamp. Validated: mock tests for good/failed/unparseable retry paths, graceful post-all, and msgId uniqueness — all pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirrors the diff the human reviewers first saw on projectcalico#12451 ('Per Pod/LB IP proxy ARP' by @MichalFupso) for the Council of Claudes benchmark. base(fork)=bbf9d864bc8b16ec93522d5eaba0b8f2164c5dbe head(as-reviewed)=b9eb6ddda00317605a351d98515bfeea3c9ce1e8
e4939cb to
50ec5c0
Compare
7e29107 to
472aef1
Compare
| // Register the proxy neighbor managers when enabled. They listen on raw sockets | ||
| // and respond to ARP (IPv4) / NDP (IPv6) requests for pod and LB IPs that fall | ||
| // within the same subnet as a host physical interface. | ||
| if config.HostSubnetNeighResponses == "PodsAndLoadBalancers" { |
There was a problem hiding this comment.
🔎 Correctness — The feature enable check is case-sensitive: if config.HostSubnetNeighResponses is set via env/YAML with different casing (allowed by the config schema), this equality will fail and the feature won’t start. Suggest using a case-insensitive check, consistent with other flags (e.g., FloatingIPsEnabled above):
if strings.EqualFold(config.HostSubnetNeighResponses, "PodsAndLoadBalancers") {
// ...
}Don’t forget to import "strings".
| // active from Felix's first calc-graph flush. | ||
| fc := api.NewFelixConfiguration() | ||
| fc.Name = "default" | ||
| fc.Spec.HostSubnetNeighResponses = new(api.HostSubnetNeighResponsesPodsAndLoadBalancers) |
There was a problem hiding this comment.
🔎 Correctness — This line won’t compile: new(api.HostSubnetNeighResponsesPodsAndLoadBalancers) attempts to use a constant as a type. Use a pointer to the constant value instead:
mode := api.HostSubnetNeighResponsesPodsAndLoadBalancers
fc.Spec.HostSubnetNeighResponses = &mode
// or, if available:
// fc.Spec.HostSubnetNeighResponses = ptr.To(api.HostSubnetNeighResponsesPodsAndLoadBalancers)| dp.RegisterManager(proxyNeighMgr6) | ||
| dp.proxyNeighManagers = append(dp.proxyNeighManagers, proxyNeighMgr6) | ||
| } | ||
| } |
There was a problem hiding this comment.
🔎 Correctness — The manager starts listener goroutines and stores them in dp.proxyNeighManagers, but there’s no corresponding shutdown to cancel contexts/close sockets when Felix stops. This risks leaking goroutines/file descriptors across teardown. Recommend invoking a cleanup during dataplane shutdown (e.g., in InternalDataplane.Stop or equivalent) to iterate dp.proxyNeighManagers and call a new Stop/Close method or expose/call m.cancel() to ensure listeners terminate.
| if ip.To4() != nil { | ||
| return "", fmt.Errorf("NeighborSolicit requires an IPv6 address, got %s", ip) | ||
| } | ||
| out, err := p.exec("rdisc6", "-1", "-w", "5000", extL2Iface, ip.String()) |
There was a problem hiding this comment.
🔎 Correctness — NeighborSolicit uses rdisc6 to send a Neighbor Solicitation. rdisc6 is typically for Router Solicitation/Discovery; for NS/NA, the ndisc6 tool (from the same suite) is usually used. On some images/environments rdisc6 may not emit NS and could cause spurious failures. Consider switching to a tool that explicitly sends a single NS (e.g., ndisc6 <addr> <iface>), or verify netshoot’s rdisc6 behavior and adjust invocation accordingly.
| // Register the proxy neighbor managers when enabled. They listen on raw sockets | ||
| // and respond to ARP (IPv4) / NDP (IPv6) requests for pod and LB IPs that fall | ||
| // within the same subnet as a host physical interface. | ||
| if config.HostSubnetNeighResponses == "PodsAndLoadBalancers" { |
There was a problem hiding this comment.
🧪 Maintainability & Tests — The manager is enabled with a direct string comparison against "PodsAndLoadBalancers". This is brittle (case sensitivity) and spreads stringly-typed policy across components.
- Suggestion:
- Normalize once at construction and pass an enum/bool to the dataplane. For example, in StartDataplaneDriver, parse with strings.EqualFold and set a typed field:
- Add to intdataplane.Config: HostSubnetNeighResponsesEnabled bool
- In driver.go: HostSubnetNeighResponsesEnabled: strings.EqualFold(configParams.HostSubnetNeighResponses, "PodsAndLoadBalancers")
- Here: if config.HostSubnetNeighResponsesEnabled { ... }
- Alternatively, if you prefer strings, at least use strings.EqualFold to match the parsing semantics used for FloatingIPs.
- Normalize once at construction and pass an enum/bool to the dataplane. For example, in StartDataplaneDriver, parse with strings.EqualFold and set a typed field:
| Hostname: felixHostname, | ||
| NodeZone: felixNodeZone, | ||
| FloatingIPsEnabled: strings.EqualFold(configParams.FloatingIPs, string(apiv3.FloatingIPsEnabled)), | ||
| HostSubnetNeighResponses: configParams.HostSubnetNeighResponses, |
There was a problem hiding this comment.
🧪 Maintainability & Tests — HostSubnetNeighResponses is plumbed through as a raw string while FloatingIPs is normalized via strings.EqualFold. This inconsistency invites regressions when values differ in case.
- Suggestion: Normalize to a boolean/enum at this boundary, matching how FloatingIPs is handled:
dpConfig.HostSubnetNeighResponsesEnabled = strings.EqualFold(configParams.HostSubnetNeighResponses, string(apiv3.HostSubnetNeighResponsesPodsAndLoadBalancers))
and pass the normalized value into intdataplane.Config.
|
|
||
| FloatingIPsEnabled bool | ||
|
|
||
| HostSubnetNeighResponses string |
There was a problem hiding this comment.
🧪 Maintainability & Tests — HostSubnetNeighResponses is stored in intdataplane.Config as a string. This leaks API details into a low-level component and forces string comparisons later.
- Suggestion: Change to a typed/normalized field (e.g., HostSubnetNeighResponsesEnabled bool or an internal enum) and keep string decoding at the config/driver boundary.
| } | ||
| } | ||
|
|
||
| // Register the proxy neighbor managers when enabled. They listen on raw sockets |
There was a problem hiding this comment.
🧪 Maintainability & Tests — Untested branching: the config gate for enabling the proxy-neighbor manager (and the IPv6 sub-manager) isn’t directly covered by a unit/integration test. Since this is the primary on/off switch, accidental regressions here would be easy to miss.
- Ask for a focused unit test (no FV/E2E needed) that:
- Constructs an InternalDataplane with HostSubnetNeighResponses disabled and asserts no proxyNeighManagers are registered.
- Constructs one with HostSubnetNeighResponses enabled and IPv6Enabled true and asserts two managers are registered (v4 + v6).
This exercises the only branch that’s not covered by your current suite and will guard future refactors.
| return fmt.Sprintf("%s/%d", out, maskOnes), nil | ||
| } | ||
|
|
||
| // v6SubnetWithSuffix returns a CIDR built by appending an IPv6 suffix CIDR |
There was a problem hiding this comment.
🧪 Maintainability & Tests — v6SubnetWithSuffix logic (IPv6 math via netip) overlaps functionally with FV’s local helpers. Consolidate into a shared test utility as noted above to prevent divergence and reduce mental overhead.
| } | ||
|
|
||
| m.listeners[ifaceName] = l | ||
| log.WithField("iface", ifaceName).Info("Started proxy neighbor listener") |
There was a problem hiding this comment.
🧪 Maintainability & Tests — Starting/stopping listeners logs at Info for every interface. On large hosts this can get noisy and drown out higher-signal logs.
- Suggestion: Consider downgrading “Started/Stopped proxy neighbor listener” to Debug, keeping a one-time “feature enabled” Info log when the manager registers.
| // neighbour entries on host interfaces for local pod IPs and LB VIPs that overlap the | ||
| // host subnet. [Default: PodsAndLoadBalancers] | ||
| HostSubnetNeighResponses string `config:"oneof(Disabled,PodsAndLoadBalancers);PodsAndLoadBalancers"` | ||
|
|
There was a problem hiding this comment.
🛡️ Security — Default enables proxy ARP/NDP on host subnets (PodsAndLoadBalancers). Risk: unexpected exposure of pod and VIP addresses to L2-adjacent networks, potentially weakening network isolation and increasing attack surface (scanning/recon, lateral-movement attempts). Mitigation: change default to Disabled; require explicit opt-in. Alternatively, gate by additional scoping (e.g., an allowlist of host interfaces or CIDR filters) and document risks prominently.
| return ip.To4() == nil | ||
| } | ||
|
|
||
| func isNoEncapPool(pool *proto.IPAMPool) bool { |
There was a problem hiding this comment.
🛡️ Security — Pool filtering only checks encapsulation mode (isNoEncapPool) and ignores AllowedUses. Risk: proxy ARP/NDP may respond for any IP within any no-encap pool, regardless of intended use, increasing chance of claiming unintended addresses (especially for LB VIPs). Mitigation: extend checks to ensure the IP belongs to a pool whose AllowedUses includes the relevant purpose (Workload for pod IPs is implicit via IPAM; LoadBalancer for VIPs should be enforced).
|
|
||
| // runARPListener listens for ARP requests on a raw socket and replies for | ||
| // IPs in the desired set. | ||
| func (m *proxyNeighManager) runARPListener(ctx context.Context, l *ifaceListener) { |
There was a problem hiding this comment.
🛡️ Security — runARPListener replies to every matching ARP request without rate limiting. Risk: L2-adjacent attacker can flood ARP requests for tracked IPs, consuming CPU in user space (potential local DoS). Mitigations: add basic per-interface/global rate limiting/backoff, or consider leveraging kernel-managed proxy_arp entries where feasible; at minimum, log and drop when exceeding thresholds.
|
|
||
| // runNDPListener listens for Neighbor Solicitations on a raw ICMPv6 socket | ||
| // and replies with Neighbor Advertisements for IPs in the desired set. | ||
| func (m *proxyNeighManager) runNDPListener(ctx context.Context, l *ifaceListener) { |
There was a problem hiding this comment.
🛡️ Security — runNDPListener replies to Neighbor Solicitations without rate limiting and sends unsolicited NAs for DAD to all-nodes multicast. Risk: high-rate NS/DAD floods from an attacker on L2 can cause CPU/bandwidth load (local DoS) and multicast churn. Mitigation: implement simple rate limiting/burst control per interface/IP, and consider bounding unsolicited NA emissions.
|
|
||
| case *proto.ServiceUpdate: | ||
| svcKey := serviceID{Namespace: msg.Namespace, Name: msg.Name} | ||
| if msg.Type != "LoadBalancer" { |
| // detectKindNetworkSubnets returns the IPv4 and IPv6 subnets configured on the | ||
| // given docker network. Either return value may be nil if the network has no | ||
| // subnet of that family. | ||
| func detectKindNetworkSubnets(networkName string) (v4, v6 *net.IPNet, err error) { |
| // Both inputs must be IPv4. We normalize to 4-byte form because net.ParseCIDR | ||
| // can return either 4- or 16-byte representations depending on the input | ||
| // string. | ||
| func subnetOffset(parent *net.IPNet, offset string) (string, error) { |
| FloatingIPsDisabled FloatingIPType = "Disabled" | ||
| ) | ||
|
|
||
| // +kubebuilder:validation:Enum=Disabled;PodsAndLoadBalancers |
There was a problem hiding this comment.
Casey — I think “Neigh” here is a bit opaque — any reason not to spell this out?
| // +kubebuilder:validation:Enum=Disabled;PodsAndLoadBalancers | |
| // +kubebuilder:validation:Enum=Disabled;PodsAndLoadBalancers | |
| type HostSubnetNeighborResponsesMode string | |
| const ( | |
| HostSubnetNeighborResponsesDisabled HostSubnetNeighborResponsesMode = "Disabled" | |
| HostSubnetNeighborResponsesPodsAndLoadBalancers HostSubnetNeighborResponsesMode = "PodsAndLoadBalancers" | |
| ) |
We tend to prefer descriptive names over abbreviations.
| allManagers []Manager | ||
| managersWithRouteTables []ManagerWithRouteTables | ||
| managersWithRouteRules []ManagerWithRouteRules | ||
| proxyNeighManagers []*proxyNeighManager |
| } | ||
|
|
||
| func newProxyNeighManager(dpConfig Config, ipVersion uint8) *proxyNeighManager { | ||
| nl, err := netlinkshim.NewRealNetlink() |
There was a problem hiding this comment.
Casey — Not sure we want a panic down in felix — can this be an error return instead so we don’t take down the process if netlink init fails?
| nl, err := netlinkshim.NewRealNetlink() | |
| nl, err := netlinkshim.NewRealNetlink() | |
| if err != nil { | |
| log.WithError(err).Error("Failed to create netlink handle for proxy neighbor manager, disabling feature") | |
| // return a no-op manager, or plumb an error up so the caller can skip registration | |
| } |
Best not to accidentally take down the cluster if we miss something!
| af arpClientFactory, | ||
| nf ndpConnFactory, | ||
| ) *proxyNeighManager { | ||
| wlIfacesPattern := "^(" + strings.Join(dpConfig.RulesConfig.WorkloadIfacePrefixes, "|") + ").*" |
There was a problem hiding this comment.
Casey — Small robustness nit: these prefixes aren’t quoted — any regex meta in the configured prefixes could be misinterpreted.
| wlIfacesPattern := "^(" + strings.Join(dpConfig.RulesConfig.WorkloadIfacePrefixes, "|") + ").*" | |
| quoted := make([]string, len(dpConfig.RulesConfig.WorkloadIfacePrefixes)) | |
| for i, p := range dpConfig.RulesConfig.WorkloadIfacePrefixes { | |
| quoted[i] = regexp.QuoteMeta(p) | |
| } | |
| wlIfacesPattern := "^(" + strings.Join(quoted, "|") + ").*" | |
| wlIfacesRegexp := regexp.MustCompile(wlIfacesPattern) |
| | `FelixConfiguration` schema | One of: <code>"Disabled"</code>, <code>"Enabled"</code>. | | ||
| | Default value (YAML) | `Disabled` | | ||
|
|
||
| ### `HostSubnetNeighResponses` (config file) / `hostSubnetNeighResponses` (YAML) |
| // ServiceUpdate just as it would in a production cluster. | ||
|
|
||
| const ( | ||
| netshootImage = "docker.io/nicolaka/netshoot:v0.13" |
There was a problem hiding this comment.
| "github.com/projectcalico/calico/e2e/pkg/utils/images" | ||
| ) | ||
|
|
||
| // proxy_neigh.go exercises the HostSubnetNeighResponses Felix feature |
| } | ||
|
|
||
| // Extract LoadBalancer ingress IPs from Status (the actual assigned IPs). | ||
| for _, ingress := range s.Status.LoadBalancer.Ingress { |
Benchmark sample reproducing the as-first-reviewed state of projectcalico/calico#12451 (by @MichalFupso).
This PR's diff equals what the human reviewers first saw: fork point
bbf9d864bc8b→ earliest human-reviewed commitb9eb6ddda003. The original PR drew 85 human top-level review comments — the ground truth to compare the Council's feedback against.🤖 Generated for the Council of Claudes benchmark.